#!/usr/bin/env python3
import requests
import json
import time
import datetime
import urllib.parse
from typing import List, Tuple, Optional, Dict, Any, Union
from requests.auth import HTTPBasicAuth

# Gerrit API配置
GERRIT_URL = "http://gerrit.gxatek.com:18080"
USERNAME = "fxxian"
PASSWORD = "KXZTcJJNwZ6yvBVeUzg2hGmUwRTHd2CHM47t2ten0w"

# 创建项目的JSON模板
PROJECT_JSON = {
    "submit_type": "INHERIT",
    "parent": "avnt/syncore_cluster/JP360/manifest"
}


def read_repos_from_file(file_path: str) -> List[str]:
    """从文件中读取仓库列表"""
    with open(file_path, "r") as file:
        repos = [line.strip() for line in file.readlines() if line.strip()]
    return repos


def create_gerrit_project(repo: str, auth: HTTPBasicAuth, json_template: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
    """创建单个Gerrit项目"""
    print(f"正在创建项目: {repo}")
    # 对仓库名称进行URL编码，确保特殊字符（如/）被正确转义
    encoded_repo = urllib.parse.quote(repo, safe='')
    url = f"{GERRIT_URL}/a/projects/{encoded_repo}"
    
    try:
        response = requests.put(
            url,
            auth=auth,
            headers={"Content-Type": "application/json"},
            data=json.dumps(json_template)
        )
        
        if response.status_code == 201:
            print(f"项目 {repo} 创建成功")
            return True, None
        else:
            error_msg = f"项目 {repo} 创建失败: {response.status_code}, {response.text}"
            print(error_msg)
            return False, error_msg
    
    except Exception as e:
        error_msg = f"创建项目 {repo} 时发生错误: {str(e)}"
        print(error_msg)
        return False, error_msg


def save_failed_projects(failed_projects: List[Tuple[str, str]], filename: str) -> str:
    """将创建失败的项目信息记录到文件中"""
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    output_file = f"{filename}_{timestamp}_failed.txt"
    
    with open(output_file, "w") as file:
        file.write(f"创建失败的项目列表 - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        file.write("=" * 80 + "\n")
        
        for project, error in failed_projects:
            file.write(f"\n项目: {project}\n")
            file.write(f"错误: {error}\n")
            file.write("-" * 50 + "\n")
    
    print(f"创建失败的项目信息已保存到文件: {output_file}")
    return output_file


def bulk_create_projects(repos_file: str, gerrit_url: str, username: str, password: str, project_template: Dict[str, Any]) -> Tuple[int, int]:
    """批量创建Gerrit项目"""
    # 读取仓库列表
    repos = read_repos_from_file(repos_file)
    
    # 设置认证信息
    auth = HTTPBasicAuth(username, password)
    
    # 统计信息
    success_count = 0
    failed_count = 0
    failed_projects: List[Tuple[str, str]] = []
    
    # 创建项目
    for repo in repos:
        success, error_msg = create_gerrit_project(repo, auth, project_template)
        if success:
            success_count += 1
        else:
            failed_count += 1
            if error_msg is not None:  # This check is to satisfy type checker
                failed_projects.append((repo, error_msg))
        
        # 添加延迟以避免过多请求
        time.sleep(0.5)
    
    print(f"所有项目创建完成，成功: {success_count}，失败: {failed_count}")
    
    # 如果存在创建失败的项目，将失败信息记录到文件中
    if failed_projects:
        failed_file = save_failed_projects(failed_projects, "failed_projects")
    
    return success_count, failed_count


def main() -> Tuple[int, int]:
    """主函数"""
    repos_file = "repo.txt"
    result = bulk_create_projects(
        repos_file=repos_file,
        gerrit_url=GERRIT_URL,
        username=USERNAME,
        password=PASSWORD,
        project_template=PROJECT_JSON
    )
    return result


if __name__ == "__main__":
    main()
